package com.sjsu.cmpe239.servlets;

import java.io.IOException;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import com.sjsu.cmpe239.Constants;
import com.sjsu.cmpe239.beans.Movie;
import com.sjsu.cmpe239.collborativeFilteringRecomender.Recommender239;
import com.sjsu.cmpe239.contentBasedRecomender.ContentBasedRecomender;
import com.sjsu.cmpe239.database.DatabaseManager;
import com.sjsu.cmpe239.services.UserService;
import com.sjsu.cmpe239.validations.UIMessages;

/**
 * Servlet implementation class login
 */
@WebServlet("/login")
public class login extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public login() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		HttpSession session = request.getSession(true);
		RequestDispatcher dispatcher;

		UserService obj = new UserService();

		session.setAttribute("loginex", null);
		String action = request.getParameter("action");

		int result = 0;
		try
		{
			if(action.equals("home")) 
			{
				//makeContentBasedSelection(request, response);
				ContentBasedRecomender  contentBasedRecomender = new ContentBasedRecomender();
				List<Movie> lTopMovies = null;
				List<Movie> lTop_Movies = null;
				List<Movie> lFinalTop_Movies = new ArrayList<Movie>();
				int userType = (Integer) session.getAttribute("userType");
				
				if(userType == 1) 
				{
					int userPref[] = getUserCategories(request, response);
					lTopMovies = contentBasedRecomender.getContentbasedRecomendation(userPref);
				} 
				else 
				{
					Recommender239 recommender239 = new Recommender239();
					int userPref[] = getUserCategories(request, response);
					lTopMovies = contentBasedRecomender.getContentbasedRecomendation(userPref);
					lTop_Movies = recommender239.recomendMovies(( Integer.parseInt(session.getAttribute("username").toString())));
				}
				
				int j = 0,k = 0;
				for(int i =0; i < 18; i++) {
					if(i < 10) {
						lFinalTop_Movies.add(lTopMovies.get(i));
					} else if(lTop_Movies != null) {
						lFinalTop_Movies.add(lTop_Movies.get(j));
						j++;
					} else if (lTop_Movies == null) {
						lFinalTop_Movies.add(lTopMovies.get(i));
					}
				}
				request.setAttribute("TopMovies", lFinalTop_Movies);
				dispatcher = getServletContext().getRequestDispatcher("/index.jsp");
				dispatcher.forward(request, response);
			}
			
			if(action.equals("loadCategories")) 
			{
				loadCategories(request, response);
			} 
			else if(action.equals("selectCategories")) 
			{
				String username = request.getParameter("email");
				String password = request.getParameter("password");
				System.out.println("Received Request is: " + username +" , " + password);
				
				result = obj.authenticateUser(username, password);
				if(result == 1 || result == 2)
				{
					System.out.println("Log in successful!");
					//set the username and password in session
					session.setAttribute("username", username);
					session.setAttribute("passowrd", password);
					session.setAttribute("userType", result);
					dispatcher = getServletContext().getRequestDispatcher("/select.jsp");
					dispatcher.forward(request, response);
				} 
				else 
				{
					session.setAttribute("loginex", UIMessages.INVALID_EMAILID_PASSWORD);
					System.out.println(UIMessages.INVALID_EMAILID_PASSWORD);
					dispatcher = getServletContext().getRequestDispatcher("/login.jsp");
					dispatcher.forward(request, response);
				} 
			} else if(action.equals("loadMovies")) {
				loadMovies(request, response);
			} else if(action.equals("showMovie")) {
				showMovie(request, response);
			} else if(action.equals("loadMovie")) {
				loadMovie(request, response);
			} 	 			
		} 
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	private void showMovie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		DatabaseManager databaseManager = new DatabaseManager();
		HttpSession session = request.getSession(true);
		session.setAttribute("movieId", request.getParameter("movieId").toString());
		RequestDispatcher dispatcher;
		dispatcher = getServletContext().getRequestDispatcher("/movieselect.jsp");
		dispatcher.forward(request, response);
	}

	private void loadMovie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		DatabaseManager databaseManager = new DatabaseManager();
		HttpSession session = request.getSession(true);
		String movie = databaseManager.getMovie(Integer.parseInt(session.getAttribute("movieId").toString()));
		response.setContentType("application/json; charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		try {
			response.getWriter().write(movie);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private int[] getUserCategories(HttpServletRequest request, HttpServletResponse response) {
		HttpSession session = request.getSession();
		String categories = "";
		if(request.getParameter("categories") != null) {
			categories = request.getParameter("categories");
			session.setAttribute("categories", request.getParameter("categories"));
		} else {
			categories = session.getAttribute("categories").toString();
		}
		System.out.println(request.getParameter("categories"));
		StringTokenizer stringTokenizer 	= new StringTokenizer(request.getParameter("categories"), "$");
		List <String> userOftenCategory 	= new ArrayList<String>();
		List <String> sometimeOftenCategory = new ArrayList<String>();
		List <String> neverOftenCategory 	= new ArrayList<String>();
		int []usrPref = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
		while(stringTokenizer.hasMoreTokens()) {
			String category = stringTokenizer.nextToken();
			if(category.indexOf("often") != -1) {
				StringTokenizer stringTokenizerCategory = new StringTokenizer(category, "_");
				stringTokenizerCategory.hasMoreTokens();
				category = stringTokenizerCategory.nextElement().toString();
				userOftenCategory.add(category);
				System.out.println(category);
			} else if(category.indexOf("sometime") != -1) {
				StringTokenizer stringTokenizerCategory = new StringTokenizer(category, "_");
				stringTokenizerCategory.hasMoreTokens();
				category = stringTokenizerCategory.nextElement().toString();
				sometimeOftenCategory.add(category);
				System.out.println(category);
			} else if(category.indexOf("never") != -1) {
				StringTokenizer stringTokenizerCategory = new StringTokenizer(category, "_");
				stringTokenizerCategory.hasMoreTokens();
				category = stringTokenizerCategory.nextElement().toString();
				userOftenCategory.add(category);
				System.out.println(category);
			}
			for(int i = 0; i < Constants.genre.length; i++) {
				if(Constants.genre[i].equals(category)) {
					usrPref[i] = 1;
					System.out.println(category + " UserSelection");
				}
			}
		}
		return usrPref;
	}
	private void loadMovies(HttpServletRequest request,
			HttpServletResponse response) {
		String page 		= request.getParameter("page");
		String sortName 	= request.getParameter("sortname");
		String sortOrder 	= request.getParameter("sortorder");
		String qtype 		= request.getParameter("qtype");
		String query	 	= request.getParameter("query");
		String rp 			= request.getParameter("rp");
		String strJSON 		= null;
		int iPage 			= 0;
		long start = System.currentTimeMillis();
		int irp			= Integer.parseInt(rp);
		if(page != null && !page.equals("")) {
			iPage = Integer.parseInt(page);
		}
		
		try {
			
			DatabaseManager databaseManager = new DatabaseManager();
			strJSON = databaseManager.listMovies(page, sortName, sortOrder, qtype, query, rp);
		} catch (NumberFormatException e) {
			strJSON = "Error in loading movies" + e;
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println(end - start);
		response.setContentType("application/json; charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		try {
			response.getWriter().write(strJSON);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private void loadCategories(HttpServletRequest request,
			HttpServletResponse response) {

		Map<String, Object> mjsonResult = new HashMap<String, Object>();
		List<Map> ljsonRow = new ArrayList<Map>();
		List<Map> ljsonCacheRow = new ArrayList<Map>();
		int i = 0;
		Map<String, Object> mapCache = new HashMap<String, Object>();
		while(i < 18) {
			Map<String, Object> mapRow = new HashMap<String, Object>();
			String[] arrString = new String [4];
			mapRow.put("id", i + "");
			arrString[0] = Constants.genre[i];
			arrString[1] = "<input type='checkbox' id='' class='category' name='often' value='" + Constants.genre[i] +  "_often'>";
			arrString[2] = "<input type='checkbox' id='' class='category' name='sometime' value=" + Constants.genre[i] +  "'_sometime'>";
			arrString[3] = "<input type='checkbox' id='' class='category' name='never' value=" + Constants.genre[i] +  "'_never'>";
			
			/*************************************************
			 * This is dynamic generation of html using JSON
			 ************************************************/
			
			mapRow.put("cell", arrString);
			ljsonCacheRow.add(mapRow);
			i++;

		}

		mjsonResult.put("page", "1");
		mjsonResult.put("total",  "18");
		mjsonResult.put("rows", ljsonCacheRow);
		JSONObject jsonObj = null;
		try {
			jsonObj = JSONObject.fromObject(mjsonResult);
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		response.setContentType("application/json; charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		try {
			response.getWriter().write(jsonObj.toString());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}
}
